package com.ggk911.pharmacy_system.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ggk911.pharmacy_system.entity.DTO.DrugInfoDTO;
import com.ggk911.pharmacy_system.entity.DrugInfo;
import com.ggk911.pharmacy_system.entity.DrugInfoType;
import com.ggk911.pharmacy_system.entity.DrugPrice;
import com.ggk911.pharmacy_system.service.impl.DrugInfoServiceImpl;
import com.ggk911.pharmacy_system.service.impl.DrugInfoTypeServiceImpl;
import com.ggk911.pharmacy_system.service.impl.DrugPriceServiceImpl;
import com.ggk911.pharmacy_system.util.RestResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 药品信息
 *
 * @author ggk-911
 * @version 1.0 2023/3/9 12:17
 */
@RestController
@RequiredArgsConstructor
@Slf4j
@CrossOrigin
@RequestMapping("/drug")
@Api(tags = "药品信息控制层")
public class DrugInfoController {
    private final DrugInfoServiceImpl service;
    private final DrugInfoTypeServiceImpl drugInfoTypeService;
    private final DrugPriceServiceImpl drugPriceService;

    //GET查询
    @GetMapping("/queryAll")
    @ApiOperation("查询所有药品信息")
    public RestResult queryAll(@RequestParam(defaultValue = "1") Integer page,
                               @RequestParam(defaultValue = "10") Integer size,
                               @RequestParam(defaultValue = "") @ApiParam("名称，别名关键字") String keyName,
                               @RequestParam(defaultValue = "") @ApiParam("制造商关键字") String manufacturer,
                               @RequestParam(defaultValue = "") @ApiParam("适应症关键字") String indications,
                               @RequestParam(defaultValue = "") @ApiParam("药品国家代码搜索") String nationalCode,
                               @RequestParam(defaultValue = "") @ApiParam("批准文号搜索") String approvalNo,
                               @ApiParam("类型搜索") Integer typeId) {
        Page<DrugInfo> drugInfoPage = new Page<>(page, size);
        LambdaQueryWrapper<DrugInfo> wrapper = new LambdaQueryWrapper<>();

        //wrapper条件
        wrapper.and(!"".equals(keyName), a -> a.like(DrugInfo::getDrugInfoName, keyName).or().like(DrugInfo::getDrugInfoAlias, keyName));
        wrapper.like(!"".equals(manufacturer), DrugInfo::getDrugInfoManufacturer, manufacturer);
        wrapper.like(!"".equals(indications), DrugInfo::getDrugInfoIndications, indications);
        wrapper.like(!"".equals(nationalCode), DrugInfo::getDrugInfoNationalCode, nationalCode);
        wrapper.like(!"".equals(approvalNo), DrugInfo::getDrugInfoApprovalNo, approvalNo);
        wrapper.eq(typeId != null, DrugInfo::getDrugInfoTypeId, typeId);

        try {
            service.page(drugInfoPage, wrapper);
//            drugInfoPage.getRecords().forEach(System.out::println);
        } catch (Exception e) {
            log.error(String.valueOf(e));
            return RestResult.error("查询错误");
        }

        return RestResult.ok("查询成功", drugInfoPage);
    }

    //GET获取所有数据集合
    @GetMapping("/list")
    public RestResult getList(@RequestParam(defaultValue = "") @ApiParam("名称，别名关键字") String keyName,
                              @RequestParam(defaultValue = "") @ApiParam("制造商关键字") String manufacturer,
                              @RequestParam(defaultValue = "") @ApiParam("适应症关键字") String indications,
                              @RequestParam(defaultValue = "") @ApiParam("药品国家代码搜索") String nationalCode,
                              @RequestParam(defaultValue = "") @ApiParam("批准文号搜索") String approvalNo,
                              @ApiParam("类型搜索") Integer typeId) {
        LambdaQueryWrapper<DrugInfo> wrapper = new LambdaQueryWrapper<>();

        //wrapper条件
        wrapper.and(!"".equals(keyName), a -> a.like(DrugInfo::getDrugInfoName, keyName).or().like(DrugInfo::getDrugInfoAlias, keyName));
        wrapper.like(!"".equals(manufacturer), DrugInfo::getDrugInfoManufacturer, manufacturer);
        wrapper.like(!"".equals(nationalCode), DrugInfo::getDrugInfoNationalCode, nationalCode);
        wrapper.like(!"".equals(indications), DrugInfo::getDrugInfoIndications, indications);
        wrapper.eq(typeId != null, DrugInfo::getDrugInfoTypeId, typeId);
        wrapper.like(!"".equals(approvalNo), DrugInfo::getDrugInfoApprovalNo, approvalNo);
        List<DrugInfo> drugInfoList = service.list(wrapper);
        return RestResult.ok("获取成功", drugInfoList);
    }

    //GET获取所有数据集合listExcel
    @SneakyThrows
    @GetMapping("/listExcel")
    public void getListExcel(@RequestParam(defaultValue = "") @ApiParam("名称，别名关键字") String keyName,
                             @RequestParam(defaultValue = "") @ApiParam("制造商关键字") String manufacturer,
                             @RequestParam(defaultValue = "") @ApiParam("适应症关键字") String indications,
                             @RequestParam(defaultValue = "") @ApiParam("药品国家代码搜索") String nationalCode,
                             @RequestParam(defaultValue = "") @ApiParam("批准文号搜索") String approvalNo,
                             @ApiParam("类型搜索") Integer typeId,
                             HttpServletResponse response) {
        LambdaQueryWrapper<DrugInfo> wrapper = new LambdaQueryWrapper<>();

        //wrapper条件
        wrapper.and(!"".equals(keyName), a -> a.like(DrugInfo::getDrugInfoName, keyName).or().like(DrugInfo::getDrugInfoAlias, keyName));
        wrapper.like(!"".equals(manufacturer), DrugInfo::getDrugInfoManufacturer, manufacturer);
        wrapper.like(!"".equals(nationalCode), DrugInfo::getDrugInfoNationalCode, nationalCode);
        wrapper.like(!"".equals(indications), DrugInfo::getDrugInfoIndications, indications);
        wrapper.eq(typeId != null, DrugInfo::getDrugInfoTypeId, typeId);
        wrapper.like(!"".equals(approvalNo), DrugInfo::getDrugInfoApprovalNo, approvalNo);
        List<DrugInfo> drugInfoList = service.list(wrapper);
        drugInfoList.forEach(System.out::println);

        //逻辑暂时放在controller

        // 设置响应头
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 设置防止中文名乱码
        String filename = URLEncoder.encode("用户列表", "utf-8");
        // 文件下载方式(附件下载还是在当前浏览器打开)
        response.setHeader("Content-disposition", "attachment;filename=" + filename + ".xls");

        // 生成excel
        ExportParams exportParams = new ExportParams();
        exportParams.setSheetName("药品信息");
        exportParams.setTitle("药品信息");
        Workbook sheets = ExcelExportUtil.exportExcel(exportParams, DrugInfo.class, drugInfoList);
        sheets.write(response.getOutputStream());
        sheets.close();
    }

    //POST表格导入
    @SneakyThrows
    @PostMapping("/importExcel")
    public RestResult importExcel(MultipartFile file) {

        //逻辑暂时放在controller
        if (file.isEmpty()) {
            throw new RuntimeException("上传文件为空");
        }
        ImportParams importParams = new ImportParams();
        importParams.setTitleRows(1);
        importParams.setHeadRows(1);
        InputStream inputStream = file.getInputStream();
        List<DrugInfoDTO> list = ExcelImportUtil.importExcel(inputStream, DrugInfoDTO.class, importParams);
        //拿到要导入的信息长度
        int size1 = list.size();
        inputStream.close();
        List<DrugInfo> drugInfoList = new ArrayList<>();
        list.forEach(item -> {
            //查询是否重复
            DrugInfo drugInfoTest = service.selectByDrugInfoNationalCode(item.getDrugInfoNationalCode());
            //类型不能为空
            if (item.getDrugInfoTypeName() != null && !"".equals(item.getDrugInfoName()) && drugInfoTest == null) {
                //通过名称取到类型ID
                int drugInfoTypeId = 0;
                try {
                    drugInfoTypeId = drugInfoTypeService.getIdByName(item.getDrugInfoTypeName());
                } catch (Exception e) {
                    return;
                }
                drugInfoList.add(new DrugInfo(item.getDrugInfoId(), item.getDrugInfoName(), item.getDrugInfoAlias(), drugInfoTypeId, item.getDrugInfoStrength(), item.getDrugInfoIndications(), item.getDrugInfoAdverseReactions(), item.getDrugInfoInteractions(), item.getDrugInfoDosage(), item.getDrugInfoSpecifications(), item.getDrugInfoStorageMethod(), item.getDrugInfoValidTime(), item.getDrugInfoManufacturer(), item.getDrugInfoNationalCode(), item.getDrugInfoApprovalNo(), item.getDrugInfoListingLicenseHolder(), null, null));
            }
        });
        //筛选后的长度
        int size = drugInfoList.size();
        if (size == 0) return RestResult.error("表中无数据或数据重复");
        if (service.saveBatch(drugInfoList)) {
            //批量导入成功后自动生成价格列
            drugInfoList.forEach(item -> {
                drugPriceService.save(new DrugPrice(item.getDrugInfoId(), 0D, null));
                log.info("添加价格ID：{}", item.getDrugInfoId());
            });
            return RestResult.ok("批量导入成功，总：" + size1 + ",成功导入：" + size);
        }
        return RestResult.error("批量导入失败");
    }

    //GET查询单个
    @GetMapping("/query/{id}")
    @ApiOperation("查询单个药品信息")
    public RestResult queryOne(@PathVariable Integer id) {
        DrugInfo drugInfo = null;
        try {
            drugInfo = service.getById(id);
        } catch (Exception e) {
            log.error("查询单个药品信息错误" + e);
            return RestResult.error("查询错误");
        }
        return RestResult.ok("查询成功", drugInfo);
    }

    //PUT插入
    @PutMapping("/insert")
    @ApiOperation("插入一条药品信息")
    public RestResult insert(DrugInfo drugInfo) {
        try {
            if (service.save(drugInfo)) {
                //药品插入成功后，药品价格插入
                if (drugPriceService.save(new DrugPrice(drugInfo.getDrugInfoId(), 0D, null))) {
                    return RestResult.ok("插入成功，药品信息编号为：" + drugInfo.getDrugInfoId(), drugInfo.getDrugInfoId());
                }
            }
        } catch (Exception e) {
            log.error(String.valueOf(e));
        }
        log.info("插入药品信息：" + drugInfo.toString());
        return RestResult.error("插入失败");
    }

    //DELETE删除
    @DeleteMapping("/delete")
    @ApiOperation("批量删除药品信息")
    public RestResult delete(Integer[] ids) {
        if (ids == null) return RestResult.error("删除失败,编号为空");

        if (!service.removeBatchByIds(Arrays.asList(ids))) return RestResult.error("删除失败");
        log.info("删除药品信息，编号为：" + Arrays.toString(ids));
        if (!drugPriceService.deleteByDrugInfoId(ids[0])) return RestResult.error("删除失败");

        return RestResult.ok("删除成功");
    }

    //POST更新
    @PostMapping("/update")
    @ApiOperation("更新一条药品信息")
    public RestResult update(DrugInfo drugInfo) {
        try {
            if (service.updateById(drugInfo)) return RestResult.ok("更新成功");
        } catch (Exception e) {
            log.error(String.valueOf(e));
        }
        return RestResult.error("更新失败");
    }
}
